<template>
  <div class="cesium-draw">
    <div id="cesium-drawer"></div>
    <div class="mouse-postion">{{ nowPostion.wgs84 }}</div>
    <div class="tool-box">
      <div class="slider-box-wrapper"><slider-box v-model:value="step" :min="1" :max="100" :step="1" /></div>
      <div class="slider-box-wrapper"><slider-bar v-model:value="curTime" :min="0" :max="timeDuration" :step="1" /></div>
      <a class="tools" @click="togglePlay" :title="playing ? '暂停' : '播放'">
        <PlayCircleOutlined v-if="!playing" />
        <PauseCircleOutlined v-if="playing" />
      </a>

      <!--<div class="select-box-wrapper"><select-box :options="commonMaterials" /></div>
      <div class="select-box-wrapper"><select-box :options="baseMaterials" /></div>
      <div class="select-box-wrapper"><select-box :options="proceduralTextures" /></div>
      <div class="select-box-wrapper"><select-box :options="miscMaterials" /></div>
      <div class="select-box-wrapper"><select-box :options="compositeMaterials" /></div>
      <div class="select-box-wrapper"><select-box :options="polylineMaterials" /></div> -->

      <!-- <div class="select-box-wrapper"><a-checkbox v-model:checked="shadows">shadows</a-checkbox></div> -->
      <!-- <div class="select-box-wrapper"><a-checkbox v-model:checked="softShadows">soft shadows</a-checkbox></div> -->
      <!-- <div class="select-box-wrapper"><a-checkbox v-model:checked="terrainShadows">terrain shadows</a-checkbox></div> -->
      <!-- <div class="select-box-wrapper"><a-checkbox v-model:checked="picking">选择</a-checkbox></div> -->
      <div id="menu">
        <!-- <p><button @click="onClick('play')">播放</button></p> -->
        <!-- <p><button @click="onClick('stop')">暂停</button></p> -->
      </div>
    </div>
  </div>
</template>

<script>
// http://earthsdk.com/v/last/Apps/Examples/?menu=true&url=./earth-heatmap-kriging.html
import { DownOutlined, EditOutlined } from '@ant-design/icons-vue';
import { PlayCircleOutlined, PauseCircleOutlined, PlayCircleFilled, PauseCircleFilled } from '@ant-design/icons-vue';
import { defineComponent, ref, watch } from 'vue';
import * as Cesium from '@cesium/Source/Cesium.js';
import MousePosition from '@functional/utils/mousePosition';
import selectBox from '@components/widgets/select-box';
import sliderBox from '@components/widgets/slider-box';
import sliderBar from '@components/widgets/slider-bar';

export default defineComponent({
  name: 'lineMaterial', // 线材质
  components: { PlayCircleOutlined, PauseCircleOutlined, DownOutlined, EditOutlined, sliderBox, sliderBar, selectBox },
  setup() {
    return {
      viewer: null,
      timer: 0,
      synchronizer: null
    };
  },
  data() {
    return {
      timeDuration: 1000,
      step: 1,
      curTime: 1,
      nowPostion: {},
      playing: true
    };
  },
  computed: {},
  watch: {},
  mounted() {
    this.initViewer();
  },
  beforeUnmount() {
    if (this.viewer) {
      this.viewer.destroy();
      this.viewer = null;
    }
  },
  methods: {
    togglePlay() {
      let vm = this;
      this.playing = !this.playing;
    },
    onViewerInited(viewer) {
      let vm = this;
      new MousePosition(viewer, pos => {
        vm.nowPostion = pos;
      });
    },
    initViewer() {
      let vm = this;
      Cesium.Ion.defaultAccessToken = $accessToken.default;
      let osm = new Cesium.ArcGisMapServerImageryProvider({
        // url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
        url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
      });
      var viewer = new Cesium.Viewer('cesium-drawer', {
        // imageryProvider: osm,
        contextOptions: {
          webgl: {
            alpha: true
          }
        },
        // shadows: true,
        animation: false,
        // baseLayerPicker: false,
        fullscreenButton: false,
        vrButton: false,
        homeButton: false,
        timeline: false,
        selectionIndicator: false,
        infoBox: false,
        // 注释时相当于使用默认地形，解开注释相当于使用全球地形
        terrainProvider: Cesium.createWorldTerrain(),
        shouldAnimate: true
      });

      //开启深度检测
      // viewer.scene.globe.depthTestAgainstTerrain = true;

      // viewer.imageryLayers._layers.forEach(e=>e.show=false);

      this.viewer = viewer;
      this.onViewerInited(viewer);
      Cesium.GroundPrimitive.initializeTerrainHeights().then(() => {
        vm.initEffects();
      });

      // this.viewer.flyTo(this.viewer.entities);
    },
    initEffects() {
      let vm = this;
      const viewer = this.viewer;
      const scene = viewer.scene;

      const y0 = 0;
      const dy = 2;
      var y = y0;

      // 1 Red dashed line
      var redLine = viewer.entities.add({
        name: 'Red dashed line',
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000]),
          width: 5,
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.RED
          })
        }
      });

      // 2 Red dashed line
      y = y + dy;
      viewer.entities.add({
        name: 'Red dashed line',
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000]),
          width: 5,
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.RED,
            dashLength: 50
          })
        }
      });

      // 3 PolylineArrow
      y = y + dy;
      viewer.entities.add({
        name: 'PolylineArrow',
        polyline: {
          width: 10,
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000]),
          material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED)
        }
      });

      // 4 aGlowLine
      y = y + dy;
      const aGlowLinePoline = {
        name: 'aGlowLine',
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000]),
          width: 10,
          material: new Cesium.PolylineGlowMaterialProperty({
            color: Cesium.Color.RED.withAlpha(0.5),
            glowPower: 0.5,
            taperPower: 0.8
          })
        }
      }
      let aGlowLine = viewer.entities.add(aGlowLinePoline);

      // 4 GroundPolylineGeometry
      y = y + dy + 1;
      var instance = new Cesium.GeometryInstance({
        geometry: new Cesium.GroundPolylineGeometry({
          width: 5,
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000])
        }),
        attributes: {}
      });
      const materialOpts = {
        fabric: {
          type: 'PolylineDash',
          uniforms: {
            color: {
              red: 1,
              green: 1,
              blue: 0,
              alpha: 1
            },
            gapColor: {
              red: 1,
              green: 1,
              blue: 1,
              alpha: 0.85
            },
            dashLength: 50
          }
        }
      };
      this._primitive = scene.primitives.add(
        new Cesium.GroundPolylinePrimitive({
          asynchronous: false,
          geometryInstances: instance,
          appearance: new Cesium.PolylineMaterialAppearance({
            material: new Cesium.Material(materialOpts)
          })
        })
      );

      // 4 PolylineGeometry
      const instance1 = new Cesium.GeometryInstance({
        geometry: new Cesium.PolylineGeometry({
          width: 15,
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000])
        }),
        attributes: {}
      });
      scene.primitives.add(
        new Cesium.Primitive({
          asynchronous: false,
          geometryInstances: instance1,
          appearance: new Cesium.PolylineMaterialAppearance({
            material: new Cesium.Material(materialOpts)
          })
        })
      );

      // 4 ColorGeometryInstanceAttribute
      y = y + dy;
      var color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE);
      var color = new Cesium.ColorGeometryInstanceAttribute(1, 1, 0, 1);
      var color = Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 0.0, 0.85));
      const instance2 = new Cesium.GeometryInstance({
        geometry: new Cesium.PolylineGeometry({
          width: 1,
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000])
        }),
        attributes: {
          show: new Cesium.ShowGeometryInstanceAttribute(true),
          color
        }
      });

      // 注册
      Cesium.Material.PolylineTypeOD = 'PolylineTypeOD';
      console.log(Cesium.Material.PolylineTypeOD);
      Cesium.Material._materialCache.addMaterial(Cesium.Material.PolylineTypeOD, {
        fabric: {
          type: Cesium.Material.PolylineTypeOD,
          uniforms: {
            color: {red: 1,green: 1,blue: 0,alpha: 1},
            totoalFrameCount: 200
          },
          source: `czm_material czm_getMaterial(czm_materialInput materialInput){\n
            czm_material material = czm_getDefaultMaterial(materialInput);\n
            vec2 st = materialInput.st;\n
            //float t = time;\n
            float t = mod(czm_frameNumber, totoalFrameCount) / totoalFrameCount;\n\n
            t *= 1.03;\n
            float alpha = smoothstep(t- 0.03, t, st.s) * step(-t, -st.s); \n
            alpha += 0.1;\n
            //alpha *= step(-0.4, -abs(0.5-st.t));\n\n
            material.diffuse = color.rgb;\n
            material.alpha = alpha;\n
            return material;\n
          }\n`
        },
        translucent: true
      });

      var material = Cesium.Material.fromType('Color', {
        // color: new Cesium.Color(1.0, 1.0, 0.0, 1.0)
      });

      var material = Cesium.Material.fromType('PolylineTypeOD', {
        color: new Cesium.Color(1.0, 1.0, 0.0, 1.0)
      });

      var appearance = new Cesium.PolylineMaterialAppearance({
        translucent: true,
        material
      });

      // var appearance = new Cesium.PolylineColorAppearance({ translucent: true });

      scene.primitives.add(
        new Cesium.Primitive({
          asynchronous: false,
          geometryInstances: instance2,
          appearance
        })
      );

      ///////////////////////////////////////////////////////////////////

      y = y + dy + 2;
      var blueLine = viewer.entities.add({
        name: 'Wide blue dashed line with a gap color',
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000]),
          width: 30,
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.BLUE,
            gapColor: Cesium.Color.YELLOW
          })
        }
      });

      y = y + dy;
      var orangeLine = viewer.entities.add({
        name: 'Orange dashed line with a short dash length',
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000]),
          width: 5,
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.ORANGE,
            dashLength: 8.0
          })
        }
      });

      y = y + dy;
      var cyanLine = viewer.entities.add({
        name: 'Cyan dashed line with a dash pattern.',
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000]),
          width: 10,
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.CYAN,
            dashPattern: parseInt('110000001111', 2)
          })
        }
      });

      y = y + 2;
      var yellowLine = viewer.entities.add({
        name: 'Yellow dashed line with a dash pattern.',
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, y, 250000, -125, y, 250000]),
          width: 10,
          material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.YELLOW,
            dashPattern: parseInt('1010101010101010', 2)
          })
        }
      });

      viewer.zoomTo(viewer.entities);
    }
  }
});
</script>

<style scoped lang="less">
.cesium-draw {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: white;
  font-size: 14px;

  #cesium-drawer {
    width: 100%;
    height: 100%;
    overflow: hidden;
    :deep(.cesium-viewer-bottom) {
      display: none !important;
    }
  }

  .mouse-postion {
    position: absolute;
    bottom: 10px;
    right: 10px;
    font-size: 14px;
    padding: 8px 12px;
    line-height: 16px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 3px;
    opacity: 0.8;
  }
}

.tool-box {
  position: absolute;
  top: 70px;
  left: 10px;
  z-index: 9;

  .tools {
    // position: absolute;
    top: 57px;
    left: 7px;
    font-size: 1.5em;
    padding: 4px 14px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 5px;
    opacity: 0.6;
    transition: all 500ms;
    &:hover {
      opacity: 0.8;
    }
  }

  #menu {
    padding-top: 20px;
    button {
      background-color: rgba(0, 0, 0, 0.75);
      border-color: rgba(0, 0, 0, 0);
      cursor: pointer;
      transition: all 500ms;
      &:hover {
        opacity: 0.75;
      }
    }
  }

  .slider-box-wrapper {
    width: 18em;
    padding: 0 10px;
    background-color: rgba(0, 0, 0, 0.75);
    margin-bottom: 10px;
  }

  .select-box-wrapper {
    padding: 5px 15px;
    background-color: rgba(0, 0, 0, 0.75);
    margin-bottom: 10px;
    width: auto;
  }
}
</style>
